/*
 * Copyright 2007-2008 Andrew O'Malley
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package ws.quokka.plugin.jee;

import org.apache.tools.ant.taskdefs.War;
import org.apache.tools.ant.types.ResourceCollection;

import ws.quokka.core.metadata.Metadata;
import ws.quokka.core.metadata.MetadataAware;
import ws.quokka.core.plugin_spi.support.Setter;
import ws.quokka.core.plugin_spi.support.TypedProperties;
import ws.quokka.core.repo_spi.RepoArtifactId;

import ws.quokka.plugin.lifecycle.LifeCycleImpl;
import ws.quokka.plugin.resources.ResourcesCopier;

import java.io.File;

import java.util.Collection;
import java.util.List;


/**
 * JeePlugin packages Java Enterprise Edition artifacts such as WARs, EJBs and EARs
 */
public class JeePlugin extends LifeCycleImpl implements MetadataAware {
    //~ Instance fields ------------------------------------------------------------------------------------------------

    private Metadata metadata;
    private ResourcesCopier resourcesCopier;

    //~ Methods --------------------------------------------------------------------------------------------------------

    public void initialise() {
        super.initialise();
        resourcesCopier = new ResourcesCopier(getProject(), log());
    }

    public void setMetadata(Metadata metadata) {
        this.metadata = metadata;
    }

    public void warTemplate() {
        RepoArtifactId id = getArtifact("war");

        War war = (War)utils().init(new War(), "war");
        war.setDestFile(getPackageFile(id));
        war.setBasedir(properties().getFile("explodedOutput"));

        // Add user generated manifest if it exists
        File manifest = properties().getFile("manifest", null);

        if ((manifest != null) && manifest.exists()) {
            war.setManifest(manifest);
        }

        Setter setter = new Setter(properties());
        setter.set(war,
            new String[] {
                "needxmlfile", "webxml", "compress", "keepcompression", "encoding", "filesonly", "whenmanifestonly",
                "update", "duplicate", "roundup", "level"
            });
        war.perform();
    }

    public void warExplodedTemplate() {
        File output = properties().getFile("output");
        utils().mkdir(output);

        copyResources("webapp.");
        copyResources("classes.");

        // Copy any libraries to WEB-INF/lib from the war path
        List path = metadata.getProjectPath(properties().getString("libPath"));
        metadata.copyPath(path, utils().normalise(output.getPath() + "/WEB-INF/lib"),
            properties().getString("libPattern"), false);
    }

    public void copyResources(String prefix) {
        TypedProperties properties = properties().sub(prefix);
        File tokensFile = utils().normalise(getTargetDir().getAbsolutePath() + "/temp/" + getShortTargetName() + "/"
                + prefix + "properties");

        String ignoredPrefix = properties.getString("ignoredTokensPrefix", "q.resources.");
        boolean addProperties = properties.getBoolean("addPropertiesAsTokens", true);

        // Copy filtered resources
        Collection filtered = properties.getMap("filtered", false, ResourceCollection.class).values();
        Collection filters = properties.getMap("filters", false, ResourceCollection.class).values();
        File output = properties.getFile("output");
        resourcesCopier.copy(filtered, output, filters, tokensFile, ignoredPrefix, addProperties);

        // Copy unfiltered resources
        Collection unfiltered = properties.getMap("unfiltered", false, ResourceCollection.class).values();
        resourcesCopier.copy(unfiltered, output);
    }

    private RepoArtifactId getArtifact(String type) {
        String artifactName = properties().getString("artifactName");
        assertTrue(artifactName.indexOf(",") == -1,
            "Multiple artifacts of type '" + type + "' have been defined: '" + artifactName
            + "'. Define a separate target for each artifact");

        return metadata.getArtifactId(artifactName, type);
    }

    private File getPackageFile(RepoArtifactId id) {
        return new File(getLifeCycle().getPackageOutput(),
            id.toPathString() + "." + metadata.getType(id.getType()).getExtension());
    }
}
